if (!window.xflib || !window.xflib.client) window.xflib = { client: {} }

window.xflib.client.toArray = function(value, splitStr = /[,!]/) {
    if (value === null) return [];
    if (Array.isArray(value)) return value;
    if ( typeof value === 'string') return value.split(splitStr);
    return [value];
}

window.xflib.client.Storage = class Storage {

    constructor(isSync = false, isRemore = true) {
        this.storageType = "storage." + (isSync ? "sync" : "local");
        this.instance = isRemore ? new window.xflib.client.RemoteStorage(this.storageType) : (isSync ? chrome.storage.sync : chrome.storage.local);
    }

}

window.xflib.client.RemoteStorage = class RemoteStorage {

    constructor(storageType) {
        this.storageType = storageType;
    }

    /**
     * 发送消息：保存数据，action=set
     * @param {*} data 
     * @param {*} product 
     * @returns 
     */
    set = function (data = null, product = "git-helper") {
        if (data && Object.keys(data).length > 0) {
            return this._send("set", data, product);
        } else {
            throw new Error("data is required");
        }
    }

    /**
     * 发送消息：获取数据，action=get
     * @param {*} data 
     * @param {*} product 
     * @returns 
     */
    get = function (data = null, product = "git-helper") {
        return this._send("get", data, product);
    }

    remove = function (data = null, product = "git-helper") {
        return this._send("remove", data, product);
    }

    clear = function () {// 不支持的操作
        return new Promise((reject) => { reject("not allowd by remote.") });
    }


    /**
     * 创建一个包装对象用于封装动作和数据
     * 
     * 此函数的主要目的是为了解决数据传输的标准化问题它通过将动作和数据封装到一个对象中，
     * 使得数据的处理更加方便和统一此外，它还允许指定产品名称和存储类型，这为多产品的数据
     * 管理提供了支持
     * 
     * @param {string} action 所执行的动作类型，例如'create'，'delete'等这是必须的参数
     * @param {Object|null} data 与动作相关联的数据默认为null如果未提供此参数，将抛出错误
     * @param {string} product 产品名称，默认为"git-helper"此参数允许在不同产品间进行切换
     * 
     * @returns {Object} 返回一个包含product、domain、action和data的对象
     * 
     * @throws {Error} 如果未提供data参数，则抛出一个错误
     */
    _warpper(action, data = null, product = "git-helper") {

        // 检查data参数是否被提供，如果没有提供则抛出错误
        if (!data) throw new Error("data is required");

        // 返回封装了产品名、存储类型、动作和数据的对象
        return {
            product: product || "git-helper",
            domain: this.storageType,
            action: action,
            data: data,
        }
    }

    /**
     * 发送消息：保存或读取数据
     * @param {*} action 
     * @param {*} data 
     * @param {*} product 
     * @returns 
     */
    _send(action, data = null, product = "git-helper") {
        return new Promise((resolve, reject) => {
            chrome.runtime.sendMessage(this._warpper(action, data, product), (response) => {
                if (response && response.success) {
                    // console.log("Received data:", response.data);
                    resolve(response.data);
                } else {
                    // console.error("Failed to get response");
                    reject(response.message);
                }
            });
        });
    }
};

// 弹窗拖拽事件
function dragElement(element) {
    var offsetX = 0, offsetY = 0, posx = 0, posy = 0;
    var elmnt = element.querySelector("#" + element.id + "-area")||element.querySelector("#" + element.id + "Area");
    var elmntHeader = element.querySelector("#" + element.id + "-header")||element.querySelector("#" + element.id + "Header");

    if (elmntHeader) {
        /* 如果存在，header 就是你移动 DIV 的地方：*/
        //elmntHeader.onmousedown = dragMouseDown;
    } else {
        /* 否则，将 DIV 从 DIV 内的任何位置移动：*/
        elmntHeader = elmnt
    }
    elmntHeader.onmousedown = dragMouseDown;

    function dragMouseDown(e) {
        e = e || window.event;
        e.preventDefault();
        // 在启动时获取鼠标光标位置：
        posx = e.clientX;
        posy = e.clientY;
        //console.log({"e.x": posx, "e.y": posy, "elmnt.offsetLeft": elmnt.offsetLeft,"elmnt.offsetTop": elmnt.offsetTop })
        document.onmouseup = closeDragElement;
        // 当光标移动时调用一个函数：
        document.onmousemove = elementDrag;
    }

    function elementDrag(e) {
        e = e || window.event;
        e.preventDefault();
        // 计算新的光标位置：
        offsetX = posx - e.clientX;
        offsetY = posy - e.clientY;
        //console.log({"e.x.offset": offsetX, "e.y.offset": offsetY, "elmnt.offsetLeft": elmnt.offsetLeft,"elmnt.offsetTop": elmnt.offsetTop})
        // 设置元素的新位置：
        elmnt.style.left = (elmnt.offsetLeft - offsetX) + "px";
        elmnt.style.top = (elmnt.offsetTop - offsetY) + "px";
        posx = e.clientX;
        posy = e.clientY;
    }

    function closeDragElement() {
        /* 释放鼠标按钮时停止移动：*/
        document.onmouseup = null;
        document.onmousemove = null;
    }
}